package main

import (
	"fmt"
)

type Animal interface {
	Sleep()
	GetType() string
	GetColor() string
}

type Dog struct {
	Color string
}

func (this *Dog) Sleep() {
	fmt.Println("狗睡觉")
}

func (this *Dog) GetType() string {
	return "dog"
}

func (this *Dog) GetColor() string {
	return this.Color
}

type Cat struct {
	Color string
}

func (this *Cat) Sleep() {
	fmt.Println("狗睡觉")
}

func (this *Cat) GetType() string {
	return "dog"
}

func (this *Cat) GetColor() string {
	return this.Color
}

func ActiveMethods(animal Animal) {
	animal.Sleep()
	fmt.Println(animal.GetType())
	fmt.Println(animal.GetColor())
}

func main() {
	var a Animal
	a = &Dog{"red"}
	a.Sleep()
	fmt.Println(a.GetType())
	fmt.Println(a.GetColor())

	b := Cat{"blue"}
	ActiveMethods(&b)

	fmt.Println("==============")
	book := Books{"peace"}
	MyFunc(book)
	MyFunc(1)
	MyFunc("zzk")
}

func MyFunc(arg interface{}) {
	fmt.Println("myFunc called")
	fmt.Println(arg)

	value, ok := arg.(string)

	if ok {
		fmt.Println("arg is a string")
		fmt.Printf("value type is %T\n", value)
	} else {
		fmt.Println("value type is not string")
	}
}

type Books struct {
	Auth string
}
